<?php
/* SVN FILE: $Id: doInstall.php 256 2010-01-05 01:09:10Z supersmashbrothers $ */
/**
* ibMarket 2
* IP.Board 3.0
* Install Plugins
*
* @author $Author: supersmashbrothers $
* @copyright $Copyright$
* @version $Revision: 256 $
* @lastrevision $Date: 2010-01-05 01:09:10 +0000 (Tue, 05 Jan 2010) $
* @modifiedby $LastChangedBy: supersmashbrothers $
* @lastmodified $LastChangedDate: 2010-01-05 01:09:10 +0000 (Tue, 05 Jan 2010) $
* @filesource $URL: http://ipb-ibmarket.googlecode.com/svn/ibmarket2/trunk/admin/applications_addon/other/ibmarket/modules_admin/plugin/doInstall.php $
*/


if ( ! defined( 'IN_ACP' ) )
{
	print "<h1>Incorrect access</h1>You cannot access this file directly. If you have recently upgraded, make sure you upgraded 'admin.php'.";
	exit();
}

class admin_ibmarket_plugin_doInstall extends ipsCommand
{
	/**
	 * Skin object
	 *
	 * @access	private
	 * @var		object			Skin templates
	 */
	private $html;
	
	/**
	 * Main class entry point
	 *
	 * @access	public
	 * @param	object		ipsRegistry reference
	 * @return	void		[Outputs to screen]
	 */
	public function doExecute( ipsRegistry $registry )
	{
		$this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'manage_plugin' );
		
		$this->registry->getClass('class_localization')->loadLanguageFile( array( 'admin_market', 'admin_plugins' ) );
		
		if($this->request['plugin'] == '..' || $this->request['plugin'] == '.' || !file_exists(IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/xml/information.xml"))
		{
			$this->registry->output->showError($this->lang->words['cannot_find_plugin']);
		}
		
		require_once( IPS_KERNEL_PATH . 'classXML.php' );
		$xml = new classXML( $this->settings['gb_char_set'] );
		
		$xml->load( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/xml/information.xml" );
		
		// How not use use the array
		if(!$xml->fetchElements('data'))
		{
			$this->registry->output->showError($this->lang->words['cannot_find_plugin']);
		}
		
		/* Sequence of Events:
			# SQL/Plugin Data
			# Templates
			# Languages
			# Tasks
			# Template Cache
			# Caches / Done
		*/		
		switch( $this->request['do'] )
		{
			default:
			case 'sql':
				$this->sql();
			break;
			case 'templates':
				$this->templates();
			break;
			case 'languages':
				$this->languages();
			break;
			case 'tasks':
				$this->tasks();
			break;
			case 'tplcache':
				$this->recacheTemplates();
			break;
			case 'finish':
				$this->finish();
			break;
		}
		
		$this->registry->getClass('output')->html_main .= $this->registry->getClass('output')->global_template->global_frame_wrapper();
		$this->registry->getClass('output')->sendOutput();
	}
	
	/**
	 * Creates Tables, Runs Inserts, and Indexes
	 *
	 * @access	public
	 * @return	void
	 **/
	public function sql()
	{
		/* INIT */
		$output		= array();
		$errors		= array();
		$skipped	= 0;
		$count		= 0;
		
		/* Any "extra" configs required for this driver? */
		if( file_exists( IPS_ROOT_PATH . 'setup/sql/' . strtolower( $this->settings['sql_driver'] ) . '_install.php' ) )
		{
			require_once( IPS_ROOT_PATH . 'setup/sql/' . strtolower( $this->settings['sql_driver'] ) . '_install.php' );
			
			$extra_install = new install_extra( $this->registry );
		}
		
		//-----------------------------------------
		// Tables
		//-----------------------------------------
		
		$this->DB->return_die = 1;
		
		if ( file_exists( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/install/" . strtolower( ipsRegistry::dbFunctions()->getDriverType() ) . "_tables.php" ) )
		{
			include( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/install/" . strtolower( ipsRegistry::dbFunctions()->getDriverType() ) . "_tables.php" );
			
			if ( is_array( $TABLE ) and count( $TABLE ) )
			{
				foreach( $TABLE as $q )
				{
					//-----------------------------------------
					// Is this a create?
					//-----------------------------------------
					
					preg_match("/CREATE TABLE (\S+)(\s)?\(/", $q, $match);
					
					if( $this->DB->getTableSchematic( $match[1] ) )
					{
						$skipped++;
						continue;
					}
					
					//-----------------------------------------
					// Is this an alter?
					//-----------------------------------------
					
					preg_match("/ALTER\s+TABLE\s+(\S+)\s+ADD\s+(\S+)\s+/i", $q, $match);
					
					if( $this->DB->checkForField( $match[2], $match[1] ) )
					{
						$skipped++;
						continue;
					}
					
					if ( $extra_install AND method_exists( $extra_install, 'process_query_create' ) )
					{
						$q = $extra_install->process_query_create( $q );
					}
					$this->DB->error = '';
					
					$this->DB->query( $q );
					
					if ( $this->DB->error )
					{
						$errors[] = $q."<br /><br />".$this->DB->error;
					}
					else
					{
						$count++;
					}
				}
			}
			
			$output[] = sprintf( $this->lang->words['redir__sql_tables'], $count, $skipped );
		}
		
		//---------------------------------------------
		// Create the fulltext index...
		//---------------------------------------------
		
		if ( $this->DB->checkFulltextSupport() )
		{
			if ( file_exists( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/install/" . strtolower( ipsRegistry::dbFunctions()->getDriverType() ) . "_fulltext.php" ) )
			{
				include( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/install/" . strtolower( ipsRegistry::dbFunctions()->getDriverType() ) . "_fulltext.php" );
				
				$count	= 0;
				
				foreach( $INDEX as $q )
				{
					//---------------------------------------------
					// Pass to handler
					//---------------------------------------------
					
					if ( $extra_install AND method_exists( $extra_install, 'process_query_index' ) )
					{
						$q = $extra_install->process_query_index( $q );
					}
					
					//---------------------------------------------
					// Pass query
					//---------------------------------------------
					$this->DB->error = '';
					$this->DB->query( $q );
					
					if ( $this->DB->error )
					{
						$errors[] = $q."<br /><br />".$this->DB->error;
					}
					else
					{
						$count++;
					}
				}
				
				$output[] = sprintf( $this->lang->words['redir__sql_indexes'], $count );
			}
		}
		
		/* INSERTS */
		if ( file_exists( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/install/" . strtolower( ipsRegistry::dbFunctions()->getDriverType() ) . "_inserts.php" ) )
		{
			$count   = 0;
			
			/* Get the SQL File */
			include( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/install/" . strtolower( ipsRegistry::dbFunctions()->getDriverType() ) . "_inserts.php" );
			
			foreach( $INSERT as $q )
			{
				/* Extra Handler */
			 	if( $extra_install AND method_exists( $extra_install, 'process_query_insert' ) )
			 	{
					$q = $extra_install->process_query_insert( $q );
				}
				
				$q = str_replace( "<%time%>", time(), $q );
				$this->DB->error = '';
				$this->DB->query( $q );
				
				if ( $this->DB->error )
				{
					$errors[] = $q."<br /><br />".$this->DB->error;
				}
				else
				{
					$count++;
				}
			}
			
			$output[] = sprintf( $this->lang->words['redir__sql_inserts'], $count );
		}
		
		$plugin = array(
							'directory' => $this->request['plugin'],
							'name' => $this->request['name'],
							'position' => count($this->caches['market_plugin']) + 1,
							'seo_name' => IPSText::makeSeoTitle($this->request['name']),
							'enabled' => 1,
						);
		
		if(is_array($this->request['VIEW']))
		{
			$plugin['view_permission'] = array_keys($this->request['VIEW']);
			if(in_array(-1,$plugin['view_permission']))
			{
				$plugin['view_permission'] = array(-1);
			}
		}
		else
		{
			$plugin['view_permission'] = array();
		}
		if(is_array($this->request['USE']))
		{
			$plugin['use_permission'] = array_keys($this->request['USE']);
			if(in_array(-1,$plugin['use_permission']))
			{
				$plugin['use_permission'] = array(-1);
			}
		}
		else
		{
			$plugin['use_permission'] = array();
		}
		$plugin['view_permission'] = implode(",",$plugin['view_permission']);
		$plugin['use_permission'] = implode(",",$plugin['use_permission']);
		
		require_once(IPSLib::getAppDir('ibmarket')."/sources/plugin/adminSettings.php");
		if(file_exists(IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/adminSettings.php"))
		{
			require_once(IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/adminSettings.php");
			$class = 'admin_settings__'.$this->request['plugin'];
			if(class_exists($class))
			{
				$settings = new $class($this->registry);
				$settings->settingsSave($plugin);
			}
		}
		
		$this->DB->error = '';
		$this->DB->insert( 'market_plugins', $plugin );
		
		if ( $this->DB->error )
		{
			$errors[] = $q."<br /><br />".$this->DB->error;
		}
		
		$this->registry->output->global_error = "";
		if($errors)
		{
			$this->registry->output->global_error .= "<strong>".$this->lang->words['sql_error']."</strong><br /><br />";
			foreach($errors as $msg)
			{
				$this->registry->output->global_error .= "<span style='color:red'>&middot; " . $msg . "</span><br />";
			}
		}
		$messages .= "<strong>{$this->lang->words['progress_report']}</strong><br /><br />";
		foreach( $output as $msg )
		{
			$messages .= "<span style='color:green'>&middot; " . $msg . "</span><br />";
		}
		
		/* Show Redirect... */
		$this->registry->output->redirect( $this->settings['base_url']."module=plugin&amp;section=doInstall&amp;plugin=".$this->request['plugin']."&amp;do=templates", $messages, 2, true );
	}
	
	/**
	 * Install templates
	 *
	 * @access	public
	 * @return	void
	 **/
	public function templates()
	{
		/* INIT */
		$output    = array();
		$errors    = array();
		
		require_once( IPS_ROOT_PATH . 'sources/classes/skins/skinFunctions.php' );
		require_once( IPS_ROOT_PATH . 'sources/classes/skins/skinCaching.php' );
		require_once( IPS_ROOT_PATH . 'sources/classes/skins/skinImportExport.php' );
		$skinFunctions	= new skinImportExport( $this->registry );
		$skinCaching	= new skinCaching( $this->registry );
		
		/* Grab skin data */
		$this->DB->build( array( 'select' => '*',
								 'from'   => 'skin_collections' ) );
								
		$this->DB->execute();
		
		while( $row = $this->DB->fetch() )
		{
			/* Bit of jiggery pokery... */
			if ( $row['set_key'] == 'default' )
			{
				$row['set_key'] = 'root';
				$row['set_id']  = 0;
			}
			
			$skinSets[ $row['set_key'] ] = $row;
		}
			
		foreach( $skinSets as $skinKey => $skinData )
		{
			/* Skin files first */
			if( file_exists( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/xml/" . $skinKey . '_templates.xml' ) )
			{
				$return = $skinFunctions->importTemplatePluginXML( $plugin, $skinKey, $skinData['set_id'], TRUE );
				
				$output[] = sprintf( $this->lang->words['redir__templates'], $return['insertCount'], $return['updateCount'], $skinData['set_name'] );
			}
			
			/* Then CSS files */
			if ( file_exists( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/xml/" . $skinKey . '_css.xml' ) )
			{
				//-----------------------------------------
				// Install
				//-----------------------------------------
				
				$return = $skinFunctions->importCSSPluginXML( $plugin, $skinKey, $skinData['set_id'] );
				
				$output[] = sprintf( $this->lang->words['redir__cssfiles'], $return['insertCount'], $return['updateCount'], $skinData['set_name'] );
			}
			
			/* And we can support replacements for good measure */
			if ( file_exists( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/xml/" . 'replacements.xml' ) )
			{
				//-----------------------------------------
				// Install
				//-----------------------------------------
				
				$return = $skinFunctions->importReplacementsXMLArchive( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/xml/" . 'replacements.xml' );
				
				$output[] = $this->lang->words['redir__replacements'];
			}
		}
		
		/* Recache */
		//$skinCaching->rebuildPHPTemplates( 0 );
		//$skinCaching->rebuildCSS( 0 );
		//$skinCaching->rebuildReplacementsCache( 0 );
		
		$messages .= "<strong>{$this->lang->words['progress_report']}</strong><br /><br />";
		foreach( $output as $msg )
		{
			$messages .= "<span style='color:green'>&middot; " . $msg . "</span><br />";
		}
		
		/* Show redirect... */
		$this->registry->output->redirect( $this->settings['base_url']."module=plugin&amp;section=doInstall&amp;plugin=".$this->request['plugin']."&amp;do=languages", $messages, 2, true );
	}
	
	/**
	 * Language Import
	 *
	 * @access	public
	 * @return	void
	 **/
	public function languages()
	{
		if ( file_exists( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin'] . '/xml/language_pack.xml' ) )
		{
			/* INIT */
			$output    = array();
			$errors    = array();
			
			/* Load the language file */
			$this->registry->class_localization->loadLanguageFile( array( 'admin_system' ) );
			
			/* Get the language stuff */
			require_once( IPS_ROOT_PATH . 'applications/core/modules_admin/languages/manage_languages.php' );
			$lang = new admin_core_languages_manage_languages( $this->registry );		
			$lang->makeRegistryShortcuts( $this->registry );	
			
			/* Loop through the xml directory and look for lang packs */
			$this->request['file_location'] = IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin'] . '/xml/language_pack.xml';
			$lang->imprtFromXML( 1, true, true );
			
			$output[] = $this->registry->output->global_message ? $this->registry->output->global_message : $this->lang->words['redir__nolanguages'];
			
			/* Clear main msg */
			$this->registry->output->global_message = '';
			
			$messages .= "<strong>{$this->lang->words['progress_report']}</strong><br /><br />";
			foreach( $output as $msg )
			{
				$messages .= "<span style='color:green'>&middot; " . $msg . "</span><br />";
			}
		}
		
		/* Show redirect... */
		$this->registry->output->redirect( $this->settings['base_url']."module=plugin&amp;section=doInstall&amp;plugin=".$this->request['plugin']."&amp;do=tasks", $messages, 2, true );
	}
	
	/**
	 * Import tasks
	 *
	 * @access	public
	 * @return	void
	 **/
	public function tasks()
	{
		/* INIT */
		$output    = array();
		$errors    = array();
		
		if( file_exists( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/xml/tasks.xml" ) )
		{
			/* Get the language class */
			require_once( IPS_ROOT_PATH . 'applications/core/modules_admin/system/taskmanager.php' );
			$task_obj = new admin_core_system_taskmanager( $this->registry );
			$task_obj->makeRegistryShortcuts( $this->registry );
			
			$task_obj->tasksImportFromXML( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/xml/tasks.xml", true );
		}
		
		$output[] = $this->registry->output->global_message ? $this->registry->output->global_message : $this->lang->words['no_tasks_for_import'];
		
		/* Clear main msg */
		$this->registry->output->global_message = '';
		
		$messages .= "<strong>{$this->lang->words['progress_report']}</strong><br /><br />";
		foreach( $output as $msg )
		{
			$messages .= "<span style='color:green'>&middot; " . $msg . "</span><br />";
		}
		
		/* Show redirect... */
		$this->registry->output->redirect( $this->settings['base_url']."module=plugin&amp;section=doInstall&amp;plugin=".$this->request['plugin']."&amp;do=tplcache", $messages, 2, true );
	}
	
	/**
	 * Rebuild PHP Templates Cache
	 *
	 * @access	public
	 * @return	void
	 */
	public function recacheTemplates()
	{
		//-----------------------------------------
		// Determine if we need to recache templates
		//-----------------------------------------
		
		$hasSkin	= false;
		
		if ( file_exists( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/xml/replacements.xml" ) )
		{
			$hasSkin	= true;
		}
		
		if( !$hasSkin )
		{
			//-----------------------------------------
			// We'll check for any of the default 3
			//-----------------------------------------
			
			if( file_exists( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/xml/root_templates.xml" ) OR
				file_exists( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/xml/lofi_templates.xml" ) OR
				file_exists( IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/xml/xmlskin_templates.xml" ) )
			{
				$hasSkin	= true;
			}
		}
		
		//-----------------------------------------
		// See if any hooks were installed..
		//-----------------------------------------
		
		if( !$hasSkin )
		{
			$this->registry->output->redirect( $this->settings['base_url']."module=plugin&amp;section=doInstall&amp;plugin=".$this->request['plugin']."&amp;do=finish", $this->lang->words['redir__no_template_re'], 2, true );
		}
		
		/* INIT */
		$setID = intval( $this->request['setID'] );
		
		require_once( IPS_ROOT_PATH . 'sources/classes/skins/skinFunctions.php' );
		require_once( IPS_ROOT_PATH . 'sources/classes/skins/skinCaching.php' );
		require_once( IPS_ROOT_PATH . 'sources/classes/skins/skinImportExport.php' );
		
		$skinFunctions = new skinImportExport( $this->registry );
		
		$this->registry->getClass('class_localization')->loadLanguageFile( array( 'admin_templates' ), 'core' );	
		
		/* Get first set id */
		if( ! $setID )
		{
			ksort( $this->registry->output->allSkins );
			$_skins = $this->registry->output->allSkins;
			$_set   = array_shift( $_skins );
			$setID  = $_set['set_id'];
		}
		
		/* Rebuild */
		$skinFunctions->rebuildPHPTemplates( $setID );
		$skinFunctions->rebuildCSS( $setID );
		$skinFunctions->rebuildReplacementsCache( $setID );
		$skinFunctions->rebuildSkinSetsCache();
		
		/* Fetch next id */
		$nextID = $setID;
		
		ksort( $this->registry->output->allSkins );
		
		foreach( $this->registry->output->allSkins as $id => $data )
		{
			if ( $id > $nextID )
			{
				$nextID = $id;
				break;
			}
		}
		if ( $nextID != $setID )
		{
			$this->registry->output->redirect( $this->settings['base_url']."module=plugin&amp;section=doInstall&amp;plugin=".$this->request['plugin']."&amp;do=tplcache&amp;setID=" . $nextID, $this->lang->words['to_recachedset'] . $this->registry->output->allSkins[ $setID ]['set_name'], 2, true );
		}
		else
		{
			$this->registry->output->redirect( $this->settings['base_url']."module=plugin&amp;section=doInstall&amp;plugin=".$this->request['plugin']."&amp;do=finish", $this->lang->words['to_recache_done'], 2, true );
		}
	}
	
	/**
	 * Finalizes installation and rebuilds caches
	 *
	 * @access	public
	 * @return	void
	 **/
	public function finish()
	{
		/* INIT */
		$this->html = $this->registry->output->loadTemplate('cp_skin_plugins');
		$output    = array();
		$errors    = array();
		
		/* Rebuild application specific caches */
		$_file = IPSLib::getAppDir('ibmarket')."/plugins/".$this->request['plugin']."/caches.php";
		
		if( file_exists( $_file ) )
		{
			require( $_file );
			
			if( is_array( $CACHE ) AND count( $CACHE ) )
			{
				foreach( $CACHE as $key => $cdata )
				{
					$this->cache->rebuildCache( $key );
				}
			}
		}
		
		ipsRegistry::cache()->rebuildCache('market_plugin','ibmarket');
		
		/* Show completed screen... */
		$this->registry->output->html .= $this->html->pluginInstalled( $data, $vars['type'] );
	}
}